#pragma once
class RoadDesign;
class RoadMileLine;
class General3dParamGen
{
public:
	virtual ZMVector<ZMPoint2D > GenUV(const ZMVector<ZMPoint3D>& vPnt) const = 0;
	virtual void GenNormalAndTangent(const ZMVector<ZMPoint3D>& vPnt, const ZMVector<int>& vInx, ZMVector<ZMPoint3D>& vNormal, ZMVector<ZMPoint3D>& vTangent) const
	{
		GenNormal(vPnt, vInx, vNormal);
		GenTangent(vPnt, vInx, vTangent);

#pragma loop(hint_parallel(8))  
		for (int i = 0; i < vPnt.size(); i++)
		{
			vTangent[i] = vNormal[i].Crossed(vTangent[i]);
			vTangent[i] = vTangent[i].Crossed(vNormal[i]);
		}
	}
protected:
	virtual void GenNormal(const ZMVector<ZMPoint3D>& vPnt, const ZMVector<int>& vInx, ZMVector<ZMPoint3D>& vNormal) const;
	virtual void GenTangent(const ZMVector<ZMPoint3D>& vPnt, const ZMVector<int>& vInx, ZMVector<ZMPoint3D>& vTangent) const;
};

class Plane3dParamGen: public General3dParamGen
{
public:
		Plane3dParamGen(const ZMReal& uPlusDivDis = 20, const ZMReal& vPlusDivDis = 20);

		~Plane3dParamGen() {};

		virtual ZMVector<ZMPoint2D > GenUV(const ZMVector<ZMPoint3D>& vPnt) const;


private:
	ZMReal m_uPlusDivDis;
	ZMReal m_vPlusDivDis;
};

class Road3dParamGen : public General3dParamGen
{
public:
	Road3dParamGen(RoadDesign& road, const ZMReal& uPlusDivMile = 20, const ZMReal& vPlusDivDis = 20);
	
	Road3dParamGen(SharedPointer<RoadMileLine>& pRoadMile, const ZMReal& uPlusDivMile = 20, const ZMReal& vPlusDivDis = 20);
	
	~Road3dParamGen();

	virtual ZMVector<ZMPoint2D > GenUV(const ZMVector<ZMPoint3D>& vPnt) const;
protected:
	virtual void GenTangent(const ZMVector<ZMPoint3D>& vPnt, const ZMVector<int>& vInx,  ZMVector<ZMPoint3D>& vTangent) const;

private:
	SharedPointer<RoadMileLine> m_pRoadMile;
	ZMReal m_uPlusDivMile;
	ZMReal m_vPlusDivDis;
};
